package com.duanjc.mergemd.utils;



import cn.hutool.core.io.resource.ResourceUtil;
import com.duanjc.mergemd.bean.DocumentContent;
import com.duanjc.mergemd.constant.FileConsts;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 本类存放常用方法的工具类，如清除、获取文件内容、方法名等
 *
 * @author cqh
 * @date 2022/03/13 17:30
 */
public class FileIOUtils {

    /**
     * 读取指定路径的文件，将内容封装到 {@code DocumentContent} 中
     *
     * @param filePath 指定路径
     * @return 包含文件内容的实例。如果注入属性失败，返回的实例的引用类型默认为null；
     * 有返回null的可能
     * @throws FileNotFoundException 当文件不存在，是个目录，或者其它原因无法读取，抛出此异常
     */
    public static DocumentContent read(String filePath) throws FileNotFoundException {
        /*BufferedReader reader = new BufferedReader(getReader(filePath));*/
        BufferedReader reader = ResourceUtil.getUtf8Reader(filePath);
        String line = null;
        Object document = null;
        Class<?> documentContentClass = DocumentContent.class;
        try {
            document = documentContentClass.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
            return null;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return null;
        }

        try {
            while ((line = reader.readLine()) != null) {
                if ("".equals(line.trim())) {
                    break;
                }
                int separateIndex = line.indexOf("=");
                String propertyName = line.substring(0, separateIndex).trim();
                String propertyValue = line.substring(separateIndex + 1).trim();
                String methodName = FileFormatUtils.getMethodName(propertyName);
                Method method = null;
                try {
                    method = documentContentClass.getDeclaredMethod(methodName, propertyValue.getClass());
                    method.invoke(document, propertyValue);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return (DocumentContent) document;
    }

    /**
     * 清空 file 实例对应的文件内容
     *
     * @param dest 要清除的文件
     * @throws IOException 文件是目录、文件不存在、其它任何原因打不开此文件，抛出此异常
     */
    public static void clear(File dest) throws IOException {
        BufferedWriter bufferedWriter = null;
        try {
            bufferedWriter = new BufferedWriter(getWriter(dest));
            bufferedWriter.write("");
            bufferedWriter.flush();
        } finally {
            bufferedWriter.close();
        }
    }

    /**
     * 使用 UTF-8 编码读取文件
     *
     * @param src 源路径
     * @return 返回输入流
     * @throws FileNotFoundException 源路径不存在
     */
    public static Reader getReader(File src) throws FileNotFoundException {
        return getReader(src.getAbsolutePath());
    }

    /**
     * 使用 UTF-8 编码读取文件
     *
     * @param src 源路径
     * @return 返回输入流
     * @throws FileNotFoundException 源路径不存在
     */
    public static Reader getReader(String src) throws FileNotFoundException {
        InputStreamReader inputStreamReader = null;
        try {
            inputStreamReader = new InputStreamReader(new FileInputStream(src), FileConsts.CHARSET_UTF8);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return inputStreamReader;
    }

    /**
     * 使用 UTF-8 编码写文件
     *
     * @param dest   源路径
     * @param append 如果为真，不会覆盖而是追加
     * @return 输出流
     * @throws FileNotFoundException 源路径不存在
     */
    public static Writer getWriter(String dest, boolean append) throws FileNotFoundException {
        OutputStreamWriter outputStreamWriter = null;
        try {
            outputStreamWriter = new OutputStreamWriter(new FileOutputStream(dest, append), FileConsts.CHARSET_UTF8);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return outputStreamWriter;
    }

    /**
     * 使用 UTF-8 编码写文件
     *
     * @param dest   源路径
     * @param append 如果为真，不会覆盖源文件，而是追加
     * @return 输出流
     * @throws FileNotFoundException 源路径不存在、无法打开、不是文件
     */
    public static Writer getWriter(File dest, boolean append) throws FileNotFoundException {
        return getWriter(dest.getAbsolutePath(), append);
    }

    /**
     * 覆盖原有文件
     *
     * @param dest 源路径
     * @return 输出流
     * @throws FileNotFoundException 源路径不存在
     */
    public static Writer getWriter(File dest) throws FileNotFoundException {
        return getWriter(dest.getAbsolutePath(), false);
    }

    /**
     * 覆盖原有文件
     *
     * @param dest 源路径
     * @return 输出流
     * @throws FileNotFoundException 源路径不存在
     */
    public static Writer getWriter(String dest) throws FileNotFoundException {
        return getWriter(dest, false);
    }
}
